#ifndef __RISCV_H__
#define __RISCV_H__

#include <device/mem.h>
#include <core/instr.h>

#define RISCV_REGS_SIZE 32

struct riscv_t{
    st_device * dev_list;   //设备列表

    mem_t * flash;          //flash空间
    riscv_word_t regs[RISCV_REGS_SIZE]; //所有通用寄存器
    riscv_word_t pc;        // pc计数寄存器
    instr_t instr;
};

#define riscv_read_reg(riscv, reg)  (riscv->regs[reg])
#define riscv_write_reg(riscv, reg, val) if ((reg != 0) && (reg < 32)) {riscv->regs[reg] = val;}
#define i_get_imm(instr) int32_t(instr.I.imm11_0 | (((instr.I.imm11_0 >> 11) & 1) ? 0xFFFFF000 : 0)) //符号扩展
#define s_get_imm(instr) (int32_t(instr.S.imm4_0 | (instr.S.imm11_5 << 5)) | (((instr.S.imm11_5 >> 6) & 1) ? 0xFFFFF000 : 0))
#define j_get_imm(instr) int32_t((instr.J.imm_10_1 << 1) | (instr.J.imm_11 << 11) | (instr.J.imm_19_12 << 12) | (instr.J.imm_20 ? 0xFFF00000 : 0))
#define b_get_imm(instr) int32_t((instr.B.imm_4_1 << 1) | (instr.B.imm_10_5 << 5) | (instr.B.imm_11 << 11) | (instr.B.imm_12 ? 0xFFFFF000 : 0))
#define s_extend_64(val) int64_t(val) | (((val >> 31) & 1) ? 0xFFFF'FFFF'0000'0000 : 0) //符号扩展

riscv_t * riscv_create (void);
void riscv_add_device(riscv_t *riscv, st_device *dev);
void riscv_set_flash (riscv_t * riscv, mem_t * dev);
void riscv_load_bin (riscv_t * riscv, QString file_name);
void riscv_reset(riscv_t * riscv);
void riscv_continue(riscv_t * riscv, int Isforever);
int riscv_mem_read(riscv_t *riscv, riscv_word_t addr, uint8_t *val, int width);
int riscv_mem_write(riscv_t *riscv, riscv_word_t addr, uint8_t *val, int width);

#endif
